/*
 * Copyright (C) 2015-2021 Swift Navigation Inc.
 * Contact: https://support.swiftnav.com
 *
 * This source is subject to the license found in the file 'LICENSE' which must
 * be be distributed together with this source. All other rights reserved.
 *
 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
 */

// This file was auto-generated from (((s.src_filename))) by generate.py. Do not modify by hand!

#include <gtest/gtest.h>
#include <libsbp/cpp/state.h>
#include <libsbp/legacy/cpp/message_traits.h>
#include <libsbp/legacy/cpp/payload_handler.h>

((*- for t in s.tests *))                                                     
((*- if t.fields *))
class Test_legacy_(((s.suite_name)))(((loop.index0))) : 
  public ::testing::Test, 
  public sbp::State, 
  public sbp::IReader, 
  public sbp::IWriter, 
  sbp::PayloadHandler<(((t.msg_type_name|convert)))>
{
public:
  Test_legacy_(((s.suite_name)))(((loop.index0)))() : 
        ::testing::Test(), 
        sbp::State(), 
        sbp::IReader(), 
        sbp::IWriter(), 
        sbp::PayloadHandler<(((t.msg_type_name|convert)))>(this), 
        last_msg_storage_(),
        last_msg_(reinterpret_cast<(((t.msg_type_name|convert)))*>(last_msg_storage_)),
        last_msg_len_(),
        last_sender_id_(), 
        n_callbacks_logged_(), 
        dummy_wr_(), 
        dummy_rd_(), 
        dummy_buff_()
  {
    set_reader(this);
    set_writer(this);
  }

  s32 read(uint8_t *buf, const uint32_t n) override
  {
    uint32_t real_n = n;
    memcpy(buf, dummy_buff_ + dummy_rd_, real_n);
    dummy_rd_ += real_n;
    return (s32)real_n;
  }

  s32 write(const uint8_t *buf, uint32_t n) override
  {
    uint32_t real_n = n;
    memcpy(dummy_buff_ + dummy_wr_, buf, real_n);
    dummy_wr_ += real_n;
    return (s32)real_n;
  }


protected:

  void handle_sbp_msg(uint16_t sender_id, uint8_t message_length, const (((t.msg_type_name|convert))) &msg) override
  {
    memcpy(last_msg_storage_, &msg, message_length);
    last_msg_len_ = message_length;
    last_sender_id_ = sender_id;
    n_callbacks_logged_++;
  }

  uint8_t last_msg_storage_[SBP_MAX_PAYLOAD_LEN];
  (((t.msg_type_name|convert))) *last_msg_;
  uint8_t last_msg_len_;
  uint16_t last_sender_id_;                                                   
  size_t n_callbacks_logged_;                                                 
  uint32_t dummy_wr_;
  uint32_t dummy_rd_;
  uint8_t dummy_buff_[1024];
};                                                                            
                                                                              
TEST_F(Test_legacy_(((s.suite_name)))(((loop.index0))), Test)     
{                                                                             
    ((*- macro compare_value(prefix, value) *))
    ((*- if value is string_type *))
    {
      const char check_string[] = { (((value|str_escape))) };
      EXPECT_EQ(memcmp(last_msg_->(((prefix))), check_string, sizeof(check_string)), 0) << "incorrect value for last_msg_->(((prefix))), expected string '" << check_string << "', is '" << last_msg_->(((prefix))) << "'";
    }
    ((*- elif value is array_type *))
    ((*- for ff in value *))((( compare_value( (((prefix))) + '[' + (((loop.index0|to_str))) + ']', (((ff))) ) )))((*- endfor *))
    ((*- elif value is dict_type *))
    ((*- for k in (((value|sorted))) *))((( compare_value( (((prefix))) + '.' + (((k))), (((value[k]))) ) )))((*- endfor *))
    ((*- elif value is float_type *))((=
        Note: the ("%.12g"|format(value)|float) filter is intended to keep float
        literal precision unchanged whether generated under Python 2.7 or 3.x. =))
    EXPECT_LT((last_msg_->(((prefix)))*100 - ((("%.12g"|format(value)|float)))*100), 0.05) << "incorrect value for (((prefix))), expected ((("%.12g"|format(value)|float))), is " << last_msg_->(((prefix)));
    ((*- else *))
    EXPECT_EQ(last_msg_->(((prefix))), (((value)))) << "incorrect value for (((prefix))), expected (((value))), is " << last_msg_->(((prefix)));
    ((*- endif *))
    ((*- endmacro *))

    ((*- macro assign_value(prefix, value) *))
    ((*- if value is string_type *))
    {
      const char assign_string[] = { (((value|str_escape))) };
      memcpy(test_msg->(((prefix))), assign_string, sizeof(assign_string));
      if (sizeof(test_msg->(((prefix)))) == 0) {
        test_msg_len = (uint8_t)(test_msg_len + sizeof(assign_string));
      }
    }
    ((*- elif value is array_type *))
    ((*- for ff in value *))
    if (sizeof(test_msg->(((prefix)))) == 0) {
      // Cope with variable length arrays
      test_msg_len = (uint8_t)(test_msg_len + sizeof(test_msg->(((prefix)))[0]));
    }
    (((- assign_value( (((prefix))) + '[' + (((loop.index0|to_str))) + ']', (((ff))) ) -)))
    ((*- endfor *))
    ((*- elif value is dict_type *))
    ((*- for k in (((value|sorted))) *))((( assign_value( (((prefix))) + '.' + (((k))), (((value[k]))) ) )))((*- endfor *))
    ((*- else *))
    test_msg->(((prefix))) = (((value)));
    ((*- endif *))
    ((*- endmacro *))

    uint8_t encoded_frame[] = { ((*- for p in t.packet_as_byte_array *))(((p))),((*- endfor *)) };

    uint8_t test_msg_storage[SBP_MAX_PAYLOAD_LEN]{};
    uint8_t test_msg_len = 0;
    ((*- if t.fields *))
    (((t.msg_type_name|convert)))* test_msg = ( (((t.msg_type_name|convert)))* )test_msg_storage;
    test_msg_len = (uint8_t)sizeof(*test_msg);
    ((*- for f in t.fieldskeys *))(((assign_value( (((f))), (((t.fields[f]))) ))))((*- endfor *))
    ((*- endif *))
                                                                              
    EXPECT_EQ(send_message( (((t.msg_type))), (((t.raw_json_obj.sender))), test_msg_len, test_msg_storage), SBP_OK);
                                                                              
    EXPECT_EQ(dummy_wr_, sizeof(encoded_frame));                               
    EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0);   
                                                                              
    while (dummy_rd_ < dummy_wr_) {                                             
      process();                                                              
    }

    EXPECT_EQ(n_callbacks_logged_, 1);
    EXPECT_EQ(last_sender_id_, (((t.raw_json_obj.sender))));
    EXPECT_EQ(last_msg_len_, test_msg_len);

    ((*- if t.fields *))
    ((*- for f in t.fieldskeys *))(((compare_value( (((f))), (((t.fields[f]))) ))))((*- endfor *))
    ((*- endif *))
}
((*- endif *))
((*- endfor *))

